# coding=utf8
import time
import uuid

from flask import Blueprint, g, request, jsonify, render_template, redirect, url_for, send_file, session
import logging
import urllib
from database import db
from models import RegistRequest, Member, Team, MemberSignLog, CheckPoint, TeamSignLog

bp = Blueprint('www', __name__, template_folder='templates/www', url_prefix='/')


@bp.route("")
def main_page():
    src = request.args.get('f', "")
    if src:
        session['src'] = src
    url = urllib.urlencode({"h": "http://running.17gaoshiqing.com/redirect"}).split("=")[1]
    return redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx636097f1cf66faa7&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect' % (url, src))


@bp.route("redirect")
def get_code():
    import requests
    code = request.args.get('code')
    r = requests.get('https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx636097f1cf66faa7&secret=2b84df7f797a35346e4706175d682991&code=%(code)s&grant_type=authorization_code' % {"code": code})
    accessToken = r.json()
    session['openid'] = accessToken.get('openid')
    return redirect(url_for("www.first_page"))

@bp.route("index")
def first_page():
    openid = session.get('openid')
    #if not openid:
    #    return redirect('www.main_page')
    return render_template("index.html", **locals())


@bp.route("teamname/check", methods=["POST"])
def team_name_uesed():
    team_name = request.form.get('name')
    if RegistRequest.query.filter(RegistRequest.teamName == team_name).first():
        return jsonify(code=500, msg=u"已经被占用了")
    return jsonify(code=200)

@bp.route("<name>.<ext>")
def static_file(name, ext):
    return send_file('static/%s.%s' % (name, ext), attachment_filename="%s.%s" % (name, ext))


@bp.route("regist/", methods=["GET", "POST"])
def register():
    from www.weixinService import AccessTokenService
    if request.method == "GET":
        ts = int(time.time())
        open_id = session.get('openid')
        member = Member.query.filter(Member.weixinId == open_id).first()
        if member:
            return redirect(url_for("www.logined"))

        accessTokenService = AccessTokenService.try_grant()
        if not accessTokenService.error_msg:
            rs, info = accessTokenService.getTicket()
            if rs:
                signitrue, nonce = accessTokenService.sign(ts, request.url)
            else:
                logging.error("TICKET:%s", info)
        else:
            logging.error("ACCESSTOKEN:%s", accessTokenService.error_msg)

        return render_template("regist.html", **locals())

    team_name = request.form.get('team_name').strip()
    if RegistRequest.query.filter(RegistRequest.teamName == team_name).first():
        return jsonify(code=500, msg=u"已经被占用了")

    mobiles = []
    leaderMobile = request.form.get('m1')
    if Member.query.filter(Member.mobile == leaderMobile).first():
        return jsonify(code=500, msg=u"号码%s已经产赛了" % leaderMobile)
    mobiles.append(leaderMobile)

    memberMobile1 = request.form.get('m2')
    if Member.query.filter(Member.mobile == memberMobile1).first():
        return jsonify(code=500, msg=u"号码%s已经产赛了" % memberMobile1)
    mobiles.append(memberMobile1)

    memberMobile2 = request.form.get('m3')
    if Member.query.filter(Member.mobile == memberMobile2).first():
        return jsonify(code=500, msg=u"号码%s已经产赛了" % memberMobile2)
    mobiles.append(memberMobile2)

    memberMobile3 = request.form.get('m4')
    if Member.query.filter(Member.mobile == memberMobile3).first():
        return jsonify(code=500, msg=u"号码%s已经产赛了" % memberMobile3)
    mobiles.append(memberMobile3)

    memberMobile4 = request.form.get('m5')
    if Member.query.filter(Member.mobile == memberMobile4).first():
        return jsonify(code=500, msg=u"号码%s已经产赛了" % memberMobile4)
    mobiles.append(memberMobile4)

    if len(list(set(mobiles))) < 5:
        return jsonify(code=500, msg=u"有重复的号码")

    client_ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)

    registRequest = RegistRequest(
        teamName=team_name,
        leaderMobile=leaderMobile,
        firstMemberMobile=memberMobile1,
        secondMemberMobile=memberMobile2,
        thirdMemberMobile=memberMobile3,
        fourthMemberMobile=memberMobile4,
        payed=0,
        src=session.get('src', '')
    )
    db.add(registRequest)
    db.flush()
    accessTokenService = AccessTokenService.try_grant()
    params = {}
    if not accessTokenService.error_msg:
        rs, info = accessTokenService.getTicket()
        logging.error("get ticket, %s, %s", rs, info)
        if rs:
            buyRs, prepayid = accessTokenService.buyItem(registRequest.id, 8800 * 5, client_ip, session['openid'])
            if buyRs:
                params = accessTokenService.prepareBuy(prepayid)
                logging.error("param:%s", params)
                db.commit()
                session["lock"] = "%s" % registRequest.id
                return jsonify(code=200, params=params, rid=registRequest.id)
            else:
                logging.error("buy item:%s, %s", buyRs, prepayid)
                db.rollback()
                return jsonify(code=500, error=u"微信支付接口访问失败")
                
        else:
            logging.error("ticket error:%s", info)
    else:
        logging.error("access Token error:%s", accessTokenService.error_msg)
    db.rollback()
    return jsonify(code=500, error=u"微信支付接口暂时无法发起支付")


@bp.route("regist/cancel", methods=["POST"])
def cancel_request():
    pid = request.args.get('rid')
    registRequest = RegistRequest.byId(pid)
    if registRequest:
        db.delete(registRequest)
        db.commit()
    return jsonify(code=200)


def _gen_pwd():
    from random import sample
    return "".join(sample('123456789012345678901234567890', 6))


@bp.route("regist/success")
def after_pay():
    pid = request.args.get('rid')
    if pid != session.get('lock'):
        logging.error("e:pid!=lock %s", session.get('lock'))
        return redirect(url_for("www.register"))
    registRequest = RegistRequest.byId(pid)
    if not registRequest:
        logging.error("e: registRequest if none")
        return redirect(url_for("www.register"))
    registRequest.payed = 1
    from sms_service import getSmsService, template_id
    smsService = getSmsService()

    team = Team(teamName=registRequest.teamName, leaderMobile=registRequest.leaderMobile, status=0)
    db.add(team)
    db.flush()

    members = 0

    pwd = _gen_pwd()
    sms_rs = smsService.send(registRequest.leaderMobile, template_id, [pwd,])
    member = Member(teamId=team.id, mobile = registRequest.leaderMobile, password=pwd, weixinId=session['openid'], status=0)
    db.add(member)
    db.flush()
    members += 1 if sms_rs else 0

    pwd = _gen_pwd()
    sms_rs = smsService.send(registRequest.firstMemberMobile, template_id, [pwd, ])
    member = Member(teamId=team.id, mobile=registRequest.firstMemberMobile, password=pwd, status=0)
    db.add(member)
    db.flush()
    members += 1 if sms_rs else 0

    pwd = _gen_pwd()
    sms_rs = smsService.send(registRequest.secondMemberMobile, template_id, [pwd, ])
    member = Member(teamId=team.id, mobile=registRequest.secondMemberMobile, password=pwd, status=0)
    db.add(member)
    db.flush()
    members += 1 if sms_rs else 0

    pwd = _gen_pwd()
    sms_rs = smsService.send(registRequest.thirdMemberMobile, template_id, [pwd, ])
    member = Member(teamId=team.id, mobile=registRequest.thirdMemberMobile, password=pwd, status=0)
    db.add(member)
    db.flush()
    members += 1 if sms_rs else 0

    pwd = _gen_pwd()
    sms_rs = smsService.send(registRequest.fourthMemberMobile, template_id, [pwd, ])
    member = Member(teamId=team.id, mobile=registRequest.fourthMemberMobile, password=pwd, status=0)
    db.add(member)
    db.flush()
    members += 1 if sms_rs else 0

    team.status = members

    db.commit()
    return redirect(url_for("www.success_view"))

@bp.route("regist/success2")
def success_view():
    return render_template("reg_success.html", **locals())

@bp.route("weixin/notify", methods=["GET", "POST"])
def notify_pay():
    logging.error(request.form)
    return "OK"

@bp.route("login", methods=["GET", "POST"])
def show_login():
    open_id = session.get('openid')
    if request.method == "GET":
        member = Member.query.filter(Member.weixinId == open_id).first()
        if open_id and member:
            return redirect(url_for('www.logined'))
        return render_template("login.html", **locals())
    mobile = request.form.get('mobile')
    password = request.form.get('password')
    openid = open_id
    member = Member.query.filter(Member.mobile == mobile).first()
    if not member:
        return jsonify(code=401)
    if member.password != password:
        return jsonify(code=401)
    member.weixinId = openid
    if member.status < 1:
        member.status = 1
    session["logined_member"] = member.id
    db.flush()
    db.commit()
    return jsonify(code=200)


@bp.route("member")
def logined():
    open_id = session.get('openid')
    if not open_id:
        open_id = uuid.uuid4().hex
    member = Member.query.filter(Member.weixinId == open_id).first()
    if not member:
        member_id = session.get("logined_member")
        if not member_id:
            return redirect(url_for('www.main_page'))
        member = Member.query.get(member_id)
        if not member:
            return redirect(url_for('www.main_page'))
    return render_template("menu.html", **locals())

@bp.route("profile")
def show_edit_profile():
    open_id = session.get('openid')
    if not open_id:
        open_id = uuid.uuid4().hex
    member = Member.query.filter(Member.weixinId == open_id).first()
    if not member:
        member_id = session.get("logined_member")
        if not member_id:
            return redirect(url_for('www.main_page'))
        member = Member.query.get(member_id)
        if not member:
            return redirect(url_for('www.main_page'))

    team = Team.byId(member.teamId)
    if team.leaderMobile == member.mobile:
        members = Member.query.filter(Member.teamId == team.id).all()
    else:
        members = [member,]
    return render_template("edit_profile.html", **locals())


@bp.route("profile/<member_id>", methods=["POST"])
def save_profile(member_id):
    member = Member.byId(int(member_id))
    if not member:
        return redirect(url_for('www.main_page'))
    realName = request.form.get('realName')
    idNo = request.form.get('idNo')
    address = request.form.get('address')
    member.realName = realName
    member.idNo = idNo
    member.address = address
    if member.status < 2:
        member.status = 2
    db.commit()
    return redirect(url_for('www.show_edit_profile'))


@bp.route("signs/<member_id>", methods=["GET"])
def sign_logs(member_id):
    from www.weixinService import AccessTokenService
    open_id = session.get('openid')
    if not open_id:
        open_id = uuid.uuid4().hex
    member = Member.query.filter(Member.weixinId == open_id).first()
    if not member:
        member_id = session.get("logined_member")
        if not member_id:
            return redirect(url_for('www.main_page'))
        member = db.query(Member).get(member_id)
        if not member:
            return redirect(url_for('www.main_page'))
    ts = int(time.time())
    accessTokenService = AccessTokenService.try_grant()
    if not accessTokenService.error_msg:
        rs, info = accessTokenService.getTicket()
        if rs:
            signitrue, nonce = accessTokenService.sign(ts, request.url)
            logging.error("sig:%s  nonce:%s", signitrue, nonce)
        else:
            logging.error("TICKET:%s", info)
    else:
        logging.error("ACCESSTOKEN:%s", accessTokenService.error_msg)

    checkpoints = db.query(CheckPoint).filter(CheckPoint.id == MemberSignLog.check_point_id, MemberSignLog.member_id == member.id).order_by(MemberSignLog.id.desc()).all()
    ct = len(checkpoints)
    return render_template("sign_logs.html", **locals())

@bp.route("signs/<member_id>/sign", methods=["POST"])
def do_sign(member_id):
    member = Member.query.get(member_id)
    if not member:
        return jsonify(code=404, info=u"成员不存在")
    key = request.form.get('key')
    checkpoint = db.query(CheckPoint).filter(CheckPoint.key == key).first()
    if not checkpoint:
        return jsonify(code=404, info=u"无效的签到二维码")
    if not db.query(TeamSignLog).filter(TeamSignLog.team_id == member.teamId, TeamSignLog.check_point_id == checkpoint.id).first():
        teamsignlog = TeamSignLog(
            team_id=member.teamId,
            check_point_id=checkpoint.id,
            check_count=0,
            first_check_ts=time.time()
        )
        db.add(teamsignlog)
        db.flush()
        memberSignLog = db.query(MemberSignLog).filter(MemberSignLog.member_id == member.id, MemberSignLog.check_point_id == checkpoint.id).first()
        if not memberSignLog:
            teamsignlog.check_count += 1
            teamsignlog.last_check_ts = time.time()
            memberSignLog = MemberSignLog(
                member_id=member.id,
                team_id=member.teamId,
                check_point_id=checkpoint.id,
                check_ts=teamsignlog.last_check_ts
            )
            db.add(memberSignLog)
            db.flush()
        db.commit()
    return jsonify(code=200)
    
